//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.eshop.modules.user.service.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eshop.api.ApiCode;
import com.eshop.api.UnAuthenticatedException;
import com.eshop.common.service.impl.BaseServiceImpl;
import com.eshop.common.utils.QueryHelpPlus;
import com.eshop.dozer.service.IGenerator;
import com.eshop.enums.BillDetailEnum;
import com.eshop.enums.Brokerage;
import com.eshop.enums.ShopCommonEnum;
import com.eshop.modules.activity.service.StoreCouponUserService;
import com.eshop.modules.cart.vo.StoreCartQueryVo;
import com.eshop.modules.order.domain.StoreOrderCartInfo;
import com.eshop.modules.order.service.StoreOrderCartInfoService;
import com.eshop.modules.order.service.StoreOrderService;
import com.eshop.modules.order.service.mapper.StoreOrderMapper;
import com.eshop.modules.order.vo.StoreOrderQueryVo;
import com.eshop.modules.product.vo.StoreProductQueryVo;
import com.eshop.modules.shop.domain.SystemUserLevel;
import com.eshop.modules.shop.service.SystemConfigService;
import com.eshop.modules.shop.service.SystemStoreStaffService;
import com.eshop.modules.user.domain.ShopUser;
import com.eshop.modules.user.domain.UserLevel;
import com.eshop.modules.user.service.SystemUserLevelService;
import com.eshop.modules.user.service.UserBillService;
import com.eshop.modules.user.service.UserLevelService;
import com.eshop.modules.user.service.UserService;
import com.eshop.modules.user.service.dto.PromUserDto;
import com.eshop.modules.user.service.dto.UserDto;
import com.eshop.modules.user.service.dto.UserMoneyDto;
import com.eshop.modules.user.service.dto.UserQueryCriteria;
import com.eshop.modules.user.service.mapper.UserBillMapper;
import com.eshop.modules.user.service.mapper.UserMapper;
import com.eshop.modules.user.vo.UserQueryVo;
import com.eshop.utils.FileUtil;
import com.github.pagehelper.PageInfo;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(
        propagation = Propagation.SUPPORTS,
        readOnly = true,
        rollbackFor = {Exception.class}
)
public class UserServiceImpl extends BaseServiceImpl<UserMapper, ShopUser> implements UserService {
    @Autowired
    private IGenerator generator;
    @Autowired
    private UserMapper yxUserMapper;
    @Autowired
    private StoreOrderMapper storeOrderMapper;
    @Autowired
    private UserBillMapper userBillMapper;
    @Autowired
    private SystemUserLevelService systemUserLevelService;
    @Autowired
    private UserLevelService userLevelService;
    @Autowired
    private StoreOrderService orderService;
    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private UserBillService billService;
    @Autowired
    private StoreCouponUserService storeCouponUserService;
    @Autowired
    private SystemStoreStaffService systemStoreStaffService;
    @Autowired
    private StoreOrderCartInfoService storeOrderCartInfoService;

    public UserServiceImpl() {
    }

    public Double[] getUserMoney(Long uid) {
        double sumPrice = this.storeOrderMapper.sumPrice(uid);
        double sumRechargePrice = this.userBillMapper.sumRechargePrice(uid);
        return new Double[]{sumPrice, sumRechargePrice};
    }

    public void incPayCount(Long uid) {
        this.yxUserMapper.incPayCount(uid);
    }

    public void decPrice(Long uid, BigDecimal payPrice) {
        this.yxUserMapper.decPrice(payPrice, uid);
    }

    public void decIntegral(Long uid, double integral) {
        this.yxUserMapper.decIntegral(integral, uid);
    }

    public List<PromUserDto> getUserSpreadGrade(Long uid, int page, int limit, Integer grade, String keyword, String sort) {
        List<ShopUser> userList = this.yxUserMapper.selectList((Wrapper)Wrappers.<ShopUser>lambdaQuery().eq(ShopUser::getSpreadUid, uid));
        List<Long> userIds = (List)userList.stream().map(ShopUser::getUid).collect(Collectors.toList());
        List<PromUserDto> list = new ArrayList();
        if (userIds.isEmpty()) {
            return list;
        } else {
            if (StrUtil.isBlank(sort)) {
                sort = "u.uid desc";
            }

            Page<ShopUser> pageModel = new Page((long)page, (long)limit);
            if (ShopCommonEnum.GRADE_0.getValue().equals(grade)) {
                list = this.yxUserMapper.getUserSpreadCountList(pageModel, userIds, keyword, sort);
            } else {
                List<ShopUser> userListT = this.yxUserMapper.selectList(Wrappers.<ShopUser>lambdaQuery().in(ShopUser::getSpreadUid, userIds));
                List<Long> userIdsT = userListT.stream().map(ShopUser::getUid).collect(Collectors.toList());
                if (userIdsT.isEmpty()) {
                    return list;
                }

                list = this.yxUserMapper.getUserSpreadCountList(pageModel, userIdsT, keyword, sort);
            }
            return list;
        }
    }

    public Map<String, Integer> getSpreadCount(Long uid) {
        int countOne = this.yxUserMapper.selectCount((Wrapper)Wrappers.<ShopUser>lambdaQuery().eq(ShopUser::getSpreadUid, uid));
        int countTwo = 0;
        List<ShopUser> userList = this.yxUserMapper.selectList((Wrapper)Wrappers.<ShopUser>lambdaQuery().eq(ShopUser::getSpreadUid, uid));
        List<Long> userIds = (List)userList.stream().map(ShopUser::getUid).collect(Collectors.toList());
        if (!userIds.isEmpty()) {
            countTwo = this.yxUserMapper.selectCount((Wrapper)Wrappers.<ShopUser>lambdaQuery().in(ShopUser::getSpreadUid, userIds));
        }

        Map<String, Integer> map = new LinkedHashMap(2);
        map.put("first", countOne);
        map.put("second", countTwo);
        return map;
    }

    public void backOrderBrokerage(StoreOrderQueryVo order) {
        String open = this.systemConfigService.getData("store_brokerage_open");
        if (!StrUtil.isBlank(open) && !ShopCommonEnum.ENABLE_2.getValue().toString().equals(open)) {
            ShopUser userInfo = (ShopUser)this.getById(order.getUid());
            System.out.println("userInfo:" + userInfo);
            if (!ObjectUtil.isNull(userInfo) && userInfo.getSpreadUid() != 0L) {
                ShopUser preUser = (ShopUser)this.getById(userInfo.getSpreadUid());
                BigDecimal brokeragePrice = this.computeProductBrokerage(order, Brokerage.LEVEL_1);
                if (brokeragePrice.compareTo(BigDecimal.ZERO) > 0) {
                    double balance = NumberUtil.add(preUser.getBrokeragePrice(), brokeragePrice).doubleValue();
                    String mark = userInfo.getNickname() + "成功消费" + order.getPayPrice() + "元,奖励推广佣金" + brokeragePrice;
                    this.billService.income(userInfo.getSpreadUid(), "获得推广佣金", BillDetailEnum.CATEGORY_1.getValue(), BillDetailEnum.TYPE_2.getValue(), brokeragePrice.doubleValue(), balance, mark, order.getId().toString());
                    this.yxUserMapper.incBrokeragePrice(brokeragePrice, userInfo.getSpreadUid());
                    this.backOrderBrokerageTwo(order);
                }
            }
        }
    }

    public void incMoney(Long uid, BigDecimal price) {
        if (price != null && price.doubleValue() > 0.0D) {
            this.yxUserMapper.incMoney(uid, price);
        }

    }

    public void incIntegral(Long uid, double integral) {
        this.yxUserMapper.incIntegral(integral, uid);
    }

    public UserQueryVo getYxUserById(Long uid) {
        return (UserQueryVo)this.generator.convert(this.getById(uid), UserQueryVo.class);
    }

    public UserQueryVo handleUser(ShopUser shopUser) {
        return (UserQueryVo)this.generator.convert(shopUser, UserQueryVo.class);
    }

    public UserQueryVo getNewYxUserById(ShopUser shopUser) {
        UserQueryVo userQueryVo = (UserQueryVo)this.generator.convert(shopUser, UserQueryVo.class);
        if (userQueryVo == null) {
            throw new UnAuthenticatedException(ApiCode.UNAUTHORIZED);
        } else {
            //设置订单详情数据，就是各种数量
            userQueryVo.setOrderStatusNum(this.orderService.orderData(shopUser.getUid()));
            //设置用户有效优惠券数量
            userQueryVo.setCouponCount(this.storeCouponUserService.getUserValidCouponCount(shopUser.getUid()));
            //设置是否有核销权限，不过这里第二个参数店铺传过去的是null，就说明没有核销权限
            userQueryVo.setCheckStatus(this.systemStoreStaffService.checkStatus(shopUser.getUid(), (Integer)null));
            //更新该用户推广的人数，就是用邀请码拉了几个人，更新一波数据，同时在内部直接更改了shopUser的推广人数
            this.setUserSpreadCount(shopUser);
            return userQueryVo;
        }
    }

    public double setLevelPrice(double price, long uid) {
        LambdaQueryWrapper<UserLevel> wrapper = new LambdaQueryWrapper();
        //查询条件为，status为1，是当前用户的会员等级，选分数最高的(一个用户是从等级1升到等级6的，所以要找最大等级)
        (((wrapper.eq(UserLevel::getStatus, ShopCommonEnum.IS_STATUS_1.getValue())).eq(UserLevel::getUid, uid)).orderByDesc(UserLevel::getGrade)).last("limit 1");
        //直接查询出该用户的最大会员等级
        UserLevel userLevel = (UserLevel)this.userLevelService.getOne(wrapper);
        SystemUserLevel systemUserLevel = new SystemUserLevel();
        if (ObjectUtil.isNotNull(userLevel)) {
            systemUserLevel = (SystemUserLevel)this.systemUserLevelService.getById(userLevel.getLevelId());
        }
        //默认不打折
        int discount = 100;
        if (ObjectUtil.isNotNull(userLevel)) {
            //有会员的话就会获取相应的折扣
            discount = systemUserLevel.getDiscount().intValue();
        }
        //0.98*price返回回去即可
        return NumberUtil.mul(NumberUtil.div((float)discount, 100.0F), price);
    }

    public void setSpread(String spread, long uid) {
        if (!StrUtil.isBlank(spread) && NumberUtil.isNumber(spread)) {
            String open = this.systemConfigService.getData("store_brokerage_open");
            if (!StrUtil.isBlank(open) && !ShopCommonEnum.ENABLE_2.getValue().toString().equals(open)) {
                ShopUser userInfo = (ShopUser)this.getById(uid);
                if (!ObjectUtil.isNull(userInfo)) {
                    if (userInfo.getSpreadUid() == null || userInfo.getSpreadUid() <= 0L) {
                        long spreadInt = Long.valueOf(spread);
                        if (spreadInt != 0L) {
                            if (spreadInt != uid) {
                                ShopUser userInfoT = (ShopUser)this.getById(spreadInt);
                                if (!ObjectUtil.isNull(userInfoT)) {
                                    if (userInfoT.getSpreadUid() != uid) {
                                        ShopUser shopUser = ShopUser.builder().spreadUid(spreadInt).spreadTime(new Date()).uid(uid).build();
                                        this.yxUserMapper.updateById(shopUser);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private void backOrderBrokerageTwo(StoreOrderQueryVo order) {
        ShopUser userInfo = (ShopUser)this.getById(order.getUid());
        ShopUser userInfoTwo = (ShopUser)this.getById(userInfo.getSpreadUid());
        if (!ObjectUtil.isNull(userInfoTwo) && userInfoTwo.getSpreadUid() != 0L) {
            ShopUser preUser = (ShopUser)this.getById(userInfoTwo.getSpreadUid());
            BigDecimal brokeragePrice = this.computeProductBrokerage(order, Brokerage.LEVEL_2);
            if (brokeragePrice.compareTo(BigDecimal.ZERO) > 0) {
                double balance = NumberUtil.add(preUser.getBrokeragePrice(), brokeragePrice).doubleValue();
                String mark = "二级推广人" + userInfo.getNickname() + "成功消费" + order.getPayPrice() + "元,奖励推广佣金" + brokeragePrice;
                this.billService.income(userInfoTwo.getSpreadUid(), "获得推广佣金", BillDetailEnum.CATEGORY_1.getValue(), BillDetailEnum.TYPE_2.getValue(), brokeragePrice.doubleValue(), balance, mark, order.getId().toString());
                this.yxUserMapper.incBrokeragePrice(brokeragePrice, userInfoTwo.getSpreadUid());
            }
        }
    }

    private BigDecimal computeProductBrokerage(StoreOrderQueryVo order, Brokerage level) {
        List<StoreOrderCartInfo> storeOrderCartInfoList = this.storeOrderCartInfoService.list(Wrappers.<StoreOrderCartInfo>lambdaQuery().in(StoreOrderCartInfo::getCartId, Arrays.asList(order.getCartId().split(","))));
        BigDecimal oneBrokerage = BigDecimal.ZERO;
        BigDecimal twoBrokerage = BigDecimal.ZERO;
        List<String> cartInfos = (List)storeOrderCartInfoList.stream().map(StoreOrderCartInfo::getCartInfo).collect(Collectors.toList());
        Iterator var7 = cartInfos.iterator();

        String storeBrokerageTwoStr;
        while(var7.hasNext()) {
            storeBrokerageTwoStr = (String)var7.next();
            StoreCartQueryVo cart = (StoreCartQueryVo)JSON.parseObject(storeBrokerageTwoStr, StoreCartQueryVo.class);
            StoreProductQueryVo storeProductVO = cart.getProductInfo();
            if (ShopCommonEnum.IS_SUB_1.getValue().equals(storeProductVO.getIsSub())) {
                oneBrokerage = NumberUtil.round(NumberUtil.add(oneBrokerage, NumberUtil.mul(cart.getCartNum(), storeProductVO.getAttrInfo().getBrokerage())), 2);
                twoBrokerage = NumberUtil.round(NumberUtil.add(twoBrokerage, NumberUtil.mul(cart.getCartNum(), storeProductVO.getAttrInfo().getBrokerageTwo())), 2);
            }
        }

        String storeBrokerageRatioStr = this.systemConfigService.getData("store_brokerage_ratio");
        storeBrokerageTwoStr = this.systemConfigService.getData("store_brokerage_two");
        if (!StrUtil.isBlank(storeBrokerageRatioStr) && NumberUtil.isNumber(storeBrokerageRatioStr)) {
            if (!StrUtil.isBlank(storeBrokerageTwoStr) && NumberUtil.isNumber(storeBrokerageTwoStr)) {
                switch(level) {
                    case LEVEL_1:
                        BigDecimal storeBrokerageRatio = NumberUtil.round(NumberUtil.div(storeBrokerageRatioStr, "100"), 2);
                        BigDecimal brokeragePrice = NumberUtil.round(NumberUtil.mul(order.getTotalPrice(), storeBrokerageRatio), 2);
                        return NumberUtil.add(oneBrokerage, brokeragePrice);
                    case LEVEL_2:
                        BigDecimal storeBrokerageTwo = NumberUtil.round(NumberUtil.div(storeBrokerageTwoStr, "100"), 2);
                        BigDecimal storeBrokerageTwoPrice = NumberUtil.round(NumberUtil.mul(order.getTotalPrice(), storeBrokerageTwo), 2);
                        return NumberUtil.add(twoBrokerage, storeBrokerageTwoPrice);
                    default:
                        return BigDecimal.ZERO;
                }
            } else {
                return twoBrokerage;
            }
        } else {
            return oneBrokerage;
        }
    }

    private void setUserSpreadCount(ShopUser shopUser) {
        int count = this.yxUserMapper.selectCount(Wrappers.<ShopUser>lambdaQuery().eq(ShopUser::getSpreadUid, shopUser.getUid()));
        shopUser.setSpreadCount(count);
        this.yxUserMapper.updateById(shopUser);
    }

    public List<PromUserDto> querySpread(Long uid, Integer grade) {
        return this.getUserSpreadGrade(uid, 1, 999, grade, "", "");
    }

    public Map<String, Object> queryAll(UserQueryCriteria criteria, Pageable pageable) {
        this.getPage(pageable);
        PageInfo<ShopUser> page = new PageInfo(this.queryAll(criteria));
        Map<String, Object> map = new LinkedHashMap(2);
        map.put("content", this.generator.convert(page.getList(), UserDto.class));
        map.put("totalElements", page.getTotal());
        return map;
    }

    public List<ShopUser> queryAll(UserQueryCriteria criteria) {
        return (this.baseMapper).selectList(QueryHelpPlus.getPredicate(ShopUser.class, criteria));
    }

    public void download(List<UserDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList();
        Iterator var4 = all.iterator();

        while(var4.hasNext()) {
            UserDto yxUser = (UserDto)var4.next();
            Map<String, Object> map = new LinkedHashMap();
            map.put("用户账户(跟accout一样)", yxUser.getUsername());
            map.put("用户密码（跟pwd）", yxUser.getPassword());
            map.put("真实姓名", yxUser.getRealName());
            map.put("生日", yxUser.getBirthday());
            map.put("身份证号码", yxUser.getCardId());
            map.put("用户备注", yxUser.getMark());
            map.put("合伙人id", yxUser.getPartnerId());
            map.put("用户分组id", yxUser.getGroupId());
            map.put("用户昵称", yxUser.getNickname());
            map.put("用户头像", yxUser.getAvatar());
            map.put("手机号码", yxUser.getPhone());
            map.put("添加时间", yxUser.getCreateTime());
            map.put("添加ip", yxUser.getAddIp());
            map.put("用户余额", yxUser.getNowMoney());
            map.put("佣金金额", yxUser.getBrokeragePrice());
            map.put("用户剩余积分", yxUser.getIntegral());
            map.put("连续签到天数", yxUser.getSignNum());
            map.put("1为正常，0为禁止", yxUser.getStatus());
            map.put("等级", yxUser.getLevel());
            map.put("推广元id", yxUser.getSpreadUid());
            map.put("推广员关联时间", yxUser.getSpreadTime());
            map.put("用户类型", yxUser.getUserType());
            map.put("是否为推广员", yxUser.getIsPromoter());
            map.put("用户购买次数", yxUser.getPayCount());
            map.put("下级人数", yxUser.getSpreadCount());
            map.put("详细地址", yxUser.getAddres());
            map.put("管理员编号 ", yxUser.getAdminid());
            map.put("用户登陆类型，h5,wechat,routine", yxUser.getLoginType());
            list.add(map);
        }

        FileUtil.downloadExcel(list, response);
    }

    public void onStatus(Long uid, Integer status) {
        if (ShopCommonEnum.IS_STATUS_1.getValue().equals(status)) {
            status = ShopCommonEnum.IS_STATUS_0.getValue();
        } else {
            status = ShopCommonEnum.IS_STATUS_1.getValue();
        }

        this.yxUserMapper.updateOnstatus(status, uid);
    }

    public void updateMoney(UserMoneyDto param) {
        ShopUser shopUser = (ShopUser)this.getById(param.getUid());
        double newMoney = 0.0D;
        String mark = "";
        if (param.getPtype() == 1) {
            mark = "系统增加了" + param.getMoney() + "余额";
            newMoney = NumberUtil.add(shopUser.getNowMoney(), param.getMoney()).doubleValue();
            this.billService.income(shopUser.getUid(), "系统增加余额", BillDetailEnum.CATEGORY_1.getValue(), BillDetailEnum.TYPE_6.getValue(), param.getMoney(), newMoney, mark, "");
        } else {
            mark = "系统扣除了" + param.getMoney() + "余额";
            newMoney = NumberUtil.sub(shopUser.getNowMoney(), param.getMoney()).doubleValue();
            if (newMoney < 0.0D) {
                newMoney = 0.0D;
            }

            this.billService.expend(shopUser.getUid(), "系统减少余额", BillDetailEnum.CATEGORY_1.getValue(), BillDetailEnum.TYPE_7.getValue(), param.getMoney(), newMoney, mark);
        }

        shopUser.setNowMoney(BigDecimal.valueOf(newMoney));
        this.saveOrUpdate(shopUser);
    }

    public void incBrokeragePrice(BigDecimal price, Long uid) {
        this.yxUserMapper.incBrokeragePrice(price, uid);
    }
}
